﻿using System;
using System.Drawing;
using System.Windows.Forms;
using System.Data;

namespace SwimmingCompetitions
{
    /// <summary>
    /// Control for presenting data for a single race type. Consists of header and table of races.
    /// </summary>
    public partial class RaceView : UserControl
    {
        private readonly CompetitionModel _competition;
        private readonly CompetitionModel.RaceData _model;
        
        public event Action<RaceView> Removed;
        private Timer _sortTimer;

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                _labelRaceTitle.Text = value;
                base.Text = value;
            }
        }

        public RaceView()
        {
            InitializeComponent();
        }

        public RaceView(CompetitionModel competition, CompetitionModel.RaceData model)
            : this()
        {
            _model = model;
            _competition = competition;
            _labelRaceTitle.Text = model.Title;
            var source = model.Table;
            //get real instance of Rank:
            for (var  i = 0; i < source.Rows.Count; ++i)
            {
                var instance = source.Rows[i][CompetitionModel.ColumnRank];
                if (instance != null &&
                    !(instance is DBNull))
                {
                    source.Rows[i][CompetitionModel.ColumnRank] =
                        Rank.GetRankByName(((Rank) instance).Title);
                }
            }
            var columnStates = CompetitionMode.Current.GetVisualModel();
            for (var i = 0; i < source.Columns.Count; ++i)
            {
                Grid.Columns[i].DataPropertyName = source.Columns[i].ColumnName;
                Grid.Columns[i].HeaderText = source.Columns[i].ColumnName;
                Grid.Columns[i].Visible = columnStates[i] != ColumnState.Hidden;
                Grid.Columns[i].ReadOnly = columnStates[i] == ColumnState.ReadOnly;
            }
            ((DataGridViewComboBoxColumn)Grid.Columns[CompetitionModel.ColumnRank]).DataSource = Rank.Ranks;
            _buttonAddEntry.Enabled = columnStates[CompetitionModel.ColumnParticipant] == ColumnState.Default;

            Grid.DataSource = source;
        }

        private void gridCellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (Grid.SelectedCells.Count == 0) return;
            AutosuggestForm dialog = null;
            if (Grid.SelectedCells[0].OwningColumn.ReadOnly) return;
            switch (Grid.SelectedCells[0].ColumnIndex)
            {
                case CompetitionModel.ColumnParticipant:
                    dialog = new AutosuggestForm(_competition.Participants);
                    dialog.Text = "Участники";
                    break;
                case CompetitionModel.ColumnTeam:
                    dialog = new AutosuggestForm(_competition.Teams);
                    dialog.Text = "Команды";
                    break;
            }
            if (dialog != null)
            {
                dialog.ItemChosen += ItemChosen;
                dialog.ShowDialog();
            }
        }

        private void ItemChosen(string value)
        {
            Grid.EndEdit();
            Grid.SelectedCells[0].Value = value;
        }

        private void rowsCountChanged()
        {
            if (Grid.Rows.Count == 0) return;
            Grid.FirstDisplayedScrollingRowIndex = Grid.Rows.Count - 1;
            //_buttonAddEntry.Top = Grid.GetRowDisplayRectangle(Grid.Rows.Count - 1, false).Bottom + Grid.Top + 2;
        }

        private void gridRowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            rowsCountChanged();
        }

        private void gridRowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            rowsCountChanged();
        }

        private void buttonAddEntryClick(object sender, EventArgs e)
        {
            _model.Table.Rows.Add();
        }

        private void buttonRemoveClick(object sender, EventArgs e)
        {
            var color = _panelHeader.BackColor;
            _panelHeader.BackColor = Color.Red;
            if (MessageBox.Show("Вы уверены, что хотите удалить раздел?", "Удаление", MessageBoxButtons.YesNo, 
                MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                _competition.Races.Remove(_model);
                if (Removed != null) Removed(this);
            }
            _panelHeader.BackColor = color;
        }

        private void gridDataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //todo:
            MessageBox.Show(/*e.Exception.Message*/"Введены некорректные данные", "Ошибка ввода", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void gridCellParsing(object sender, DataGridViewCellParsingEventArgs e)
        {
            if (e.ColumnIndex == CompetitionModel.ColumnRank)
            {
                e.Value = Rank.GetRankByName(e.Value.ToString());
                e.ParsingApplied = true;
            }
            else if (e.DesiredType == typeof(TimeSpan))
            {
                var time = SwimmingGlobals.ConvertToTimeSpan(e.Value.ToString());
                if (time != null)
                {
                    e.Value = time.Value;
                    e.ParsingApplied = true;
                }
            }
        }

        private void checkRaceFinish()
        {
            var all = true;
            for (var i = 0; i < _model.Table.Rows.Count; ++i)
            {
                if (_model.Table.Rows[i][CompetitionModel.ColumnScore] is DBNull)
                {
                    all = false;
                    break;
                }
            }
            if (all)
            {
                _sortTimer = new Timer();
                _sortTimer.Enabled = true;
                _sortTimer.Interval = 1;
                _sortTimer.Tick += (s, a) =>
                {
                        _sortTimer.Enabled = false;
                        if (MessageBox.Show(
                            "Рассчитаны очки для всех участников. Отсортировать участников по очкам?",
                            "Результаты",
                            MessageBoxButtons.YesNo,
                            MessageBoxIcon.Question,
                            MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                        {
                            Grid.Sort(Grid.Columns[CompetitionModel.ColumnScore], System.ComponentModel.ListSortDirection.Ascending);
                        }
                        _sortTimer.Dispose();                        
                    };
            }
        }
        
        private void gridCellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            CompetitionMode.Current.ProcessCellChanged(_model, e);            
            checkRaceFinish();
        }
        
        private void buttonPrintClick(object sender, EventArgs e)
        {
            using (var print = new TablePublisher(_model.Table, _labelRaceTitle.Text, CompetitionMode.Current.GetVisualModel()))
            {
                print.PrintPreview();
            }
        }

        private void gridCellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            try
            {
                if (e.ColumnIndex == CompetitionModel.ColumnDefaultTime || e.ColumnIndex == CompetitionModel.ColumnTime)
                {
                    var t = (TimeSpan) e.Value;
                    e.Value = string.Format("{0:00}:{1:00}:{2:00}.{3:D3}", t.Hours, t.Minutes, t.Seconds,
                                            t.Milliseconds);
                }
            }
            catch
            {
            }
        }
    }
}
